package com.glkj.vipsystem.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.glkj.vipsystem.common.exception.BizException;
import com.glkj.vipsystem.common.utils.Constant;
import com.glkj.vipsystem.entity.ao.CompanyAO;
import com.glkj.vipsystem.entity.ao.EmployeeAO;
import com.glkj.vipsystem.entity.ao.ShopAO;
import com.glkj.vipsystem.mapper.EmployeeMapper;
import com.glkj.vipsystem.modules.sys.entity.SysUserEntity;
import com.glkj.vipsystem.modules.sys.entity.SysUserRoleEntity;
import com.glkj.vipsystem.modules.sys.service.SysUserRoleService;
import com.glkj.vipsystem.modules.sys.service.SysUserService;
import com.glkj.vipsystem.service.ICompanyService;
import com.glkj.vipsystem.service.IEmployeeService;
import com.glkj.vipsystem.service.IShopService;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * Employee 服务实现类
 * </p>
 *
 * @author Limuchan
 * @since 2019-09-03 11:17:36
 */
@Service
public class EmployeeService extends ServiceImpl<EmployeeMapper, EmployeeAO> implements IEmployeeService {
    @Resource
    private SysUserService sysUserService;
    @Resource
    private SysUserRoleService sysUserRoleService;
    @Resource
    private IShopService shopService;
    @Resource
    private ICompanyService companyService;

    @Override
    public EmployeeAO selectByUsername(String username) {
        if (StringUtils.isBlank(username)) {
            return null;
        }
        return this.selectOne(
                new EntityWrapper<EmployeeAO>()
                        .eq("username", username)
                        .last("limit 1")
        );
    }

    /**
     * 新增员工
     *
     * @param employee 员工信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(EmployeeAO employee, Long createUserId) {
        if (employee == null) {
            throw new BizException("员工信息错误");
        }
        // 校验店铺下的员工数量
        Integer shopId = employee.getShopId();
        ShopAO shop = shopService.selectById(shopId);
        if (shop == null) throw new BizException("店铺不存在");
        CompanyAO companyAO = companyService.selectById(shop.getCompanyId());
        if (companyAO == null) throw new BizException("公司不存在");
        Integer maxEmployeeNum = companyAO.getMaxEmployeeNum();
        if (maxEmployeeNum > -1) {
            // 不是负数 代表有员工数量限制
            // 计算店铺下的员工数量
            int employeeNum = this.selectCount(
                    new EntityWrapper<EmployeeAO>()
                            .eq("shop_id", shopId)
            );
            if (employeeNum >= maxEmployeeNum) {
                throw new BizException("店铺下的员工数量已达上限");
            }
        }

        // 新增管理员
        SysUserEntity sysUser = new SysUserEntity();
        sysUser.setStatus(1);
        sysUser.setCreateUserId(createUserId);
        sysUser.setUsername(employee.getUsername());
        sysUser.setPassword(employee.getPassword());
        sysUser.setCreateTime(new Date());

        // 公司管理员角色
        List<Long> roleIds = new ArrayList<>();
        roleIds.add(Constant.Role.EMPLOYEE.getValue());
        sysUser.setRoleIdList(roleIds);

        try {
            sysUserService.save(sysUser);
        } catch (DuplicateKeyException e) {
            throw new BizException("登录账号重复");
        }

        // 保存员工信息
        try {
            employee.setStatus(1);
            employee.setCreateTime(new Date());
            super.insert(employee);
        } catch (DuplicateKeyException e) {
            throw new BizException("员工电话重复");
        }
    }

    /**
     * 修改员工信息
     *
     * @param employee 员工信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(EmployeeAO employee) {
        // 若修改密码 修改登录账号的密码
        String username = employee.getUsername();
        SysUserEntity sysUserEntity = sysUserService.queryByUserName(username);
        if (sysUserEntity != null) {
            if (StringUtils.isNotBlank(employee.getPassword())) {
                sysUserEntity.setPassword(new Sha256Hash(employee.getPassword(), sysUserEntity.getSalt()).toHex());
            } else {
                sysUserEntity.setPassword(null);
            }
            sysUserEntity.setStatus(employee.getStatus());
            sysUserService.updateById(sysUserEntity);
        }

        // 修改员工信息
        try {
            super.updateById(employee);
        } catch (DuplicateKeyException e) {
            throw new BizException("员工电话重复");
        }
    }

    /**
     * 批量删除
     *
     * @param ids 要删除的id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteBatch(List<Integer> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return;
        }
        StringBuilder employeeIdsSb = new StringBuilder();
        for (Integer companyId : ids) {
            employeeIdsSb.append(",").append(companyId);
        }
        String employeeIdsStr = employeeIdsSb.toString().substring(1);
        // 删除公司管理员后台登录账号
        List<SysUserEntity> userEntityList = sysUserService.selectList(
                new EntityWrapper<SysUserEntity>()
                        .where("username in (select username from t_employee where id in (" + employeeIdsStr + "))")
        );
        if (!CollectionUtils.isEmpty(userEntityList)) {
            List<Long> userIds = new ArrayList<>();
            for (SysUserEntity sysUserEntity : userEntityList) {
                userIds.add(sysUserEntity.getUserId());
            }
            sysUserService.deleteBatchIds(userIds);
            sysUserRoleService.delete(
                    new EntityWrapper<SysUserRoleEntity>()
                            .in("user_id", userIds)
            );
        }

        // 删除员工
        this.deleteBatchIds(ids);
    }
}